package com.bridgeintelligent.tag.customer.service;

import cn.hutool.core.date.DateUtil;
import com.bridgeintelligent.tag.constants.bulkload.IssueMqMsg;
import com.bridgeintelligent.tag.constants.bulkload.MQConfig;
import com.bridgeintelligent.tag.customer.entity.IssueLog;
import com.bridgeintelligent.tag.customer.entity.IssuePending;
import com.bridgeintelligent.tag.customer.entity.IssueTaskLog;
import com.bridgeintelligent.tag.customer.exception.CustomersException;
import com.bridgeintelligent.tag.customer.mapper.IssueLogMapper;
import com.bridgeintelligent.tag.customer.mapper.IssueTaskMapper;
import com.bridgeintelligent.tag.customer.vo.IssueTaskVO;
import com.bridgeintelligent.tag.utils.DateHelper;
import com.bridgeintelligent.tag.utils.IdWorker;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wayneleo.quickstart.framework.ExceptionCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLIntegrityConstraintViolationException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

/**
 * @description
 * @author: grp 2021-03-01 17:46
 **/
@Service
@Slf4j
@AllArgsConstructor
public class IssueSendServiceImpl implements IIssueSendService {
    private final IssueTaskMapper issueTaskMapper;
    private final IssueLogMapper issueLogMapper;

    protected RocketMQTemplate rocketMQTemplate;
    private ObjectMapper objectMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendByTaskId(String taskId) {
        IssueTaskVO task = issueTaskMapper.findOne(taskId);
        String dataDate = getDataDate(task);
        int count = issueTaskMapper.countPending(task.getId()+"-"+dataDate);
        if(count>0){
            log.info(task.getId()+"-"+dataDate+" 任务已处理过");
            return;
        }
        count = issueTaskMapper.countStartAndEnd(task.getId(),dataDate);
        if(count>0){
            log.info("下发任务已执行：{}-{}",task.getId(),dataDate);
            return;
        }
        IssueTaskLog taskLog = new IssueTaskLog();
        BeanUtils.copyProperties(task, taskLog);
        taskLog.setIssueId(task.getId());
        taskLog.setId(IdWorker.nextId());
        taskLog.setIsDel("00");
        IssuePending pending = new IssuePending().setId(task.getId()+"-"+dataDate).setCreateTime(new Date())
                .setLogId(taskLog.getId());
        issueLogMapper.addPending(pending);
        issueLogMapper.addTaskLog(taskLog);
        IssueLog issueLog = new IssueLog();
        issueLogMapper.addLog(issueLog.setId(taskLog.getId())
                .setUpdateTime(new Date()).setCreateTime(new Date()).setDataDate(dataDate)
                .setState("0").setIsRetry("0"));
    }

    private String getDataDate(IssueTaskVO task) {
        //定时任务不处理立即下发任务
        if(StringUtils.equals("1",task.getFrequency())){
            throw new CustomersException(new ExceptionCode(999,"不支持的立即下发频度"));
        }
        //遇到周频率 判断当前周几与设置周几是否相同，不同则此次定时不做任何操作，
        // 相同则返回最新es时间，添加一条执行任务
        if (StringUtils.equals("3",task.getFrequency())){
            String weekNow = DateUtil.dayOfWeekEnum(new Date())+"";
            if (StringUtils.isEmpty(task.getWeeks()) || !StringUtils.equals(weekNow,task.getWeeks())){
                throw new CustomersException(new ExceptionCode(999,"当前周："+weekNow+" 与预设周："+task.getWeeks()+" 不匹配"));
            }else{
                return DateHelper.currentDateTime("yyyyMMdd");
                //return issueTaskMapper.indexLastTime(task.getIndexId());
            }
        }
        //遇到月频率，计算上月日期并返回
        Calendar c = Calendar.getInstance();
        c.set(Calendar.MONTH, c.get(Calendar.MONTH) - 1);
        Date day =  c.getTime();
        return new SimpleDateFormat("yyyyMM").format(day);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendByLogId(String logId) throws SQLIntegrityConstraintViolationException {
        IssueTaskLog taskLog = issueLogMapper.findOneTaskLog(logId);
        IssueLog lastIssueLog = issueLogMapper.findOneLog(logId);

        //根据tasklog表里的issueId（task表的主键ID）查询最新的输出项
        IssueTaskVO issueTaskVO = Objects.requireNonNull(issueTaskMapper.findOne(taskLog.getIssueId()));
        taskLog.setFields(issueTaskVO.getFields());

        if (!"1".equals(taskLog.getFrequency())){
            String dataDate = lastIssueLog.getDataDate();
            taskLog.setId(IdWorker.nextId());
            taskLog.setIsDel("00");
            IssuePending pending = new IssuePending().setId(taskLog.getIssueId()+"-"+dataDate).setCreateTime(new Date())
                    .setLogId(taskLog.getId());
            issueLogMapper.addPending(pending);
            issueLogMapper.addTaskLog(taskLog);
            IssueLog issueLog = new IssueLog();
            issueLogMapper.addLog(issueLog.setId(taskLog.getId())
                    .setUpdateTime(new Date()).setCreateTime(new Date()).setDataDate(dataDate)
                    .setState("0").setIsRetry("1"));
        }else{
            //立即下发功能
            String dataDate = issueTaskMapper.indexLastTime(issueTaskVO.getIndexId());
            taskLog.setId(IdWorker.nextId());
            taskLog.setIsDel("00");
            issueLogMapper.addTaskLog(taskLog);
            IssueLog issueLog = new IssueLog();
            issueLogMapper.addLog(issueLog.setId(taskLog.getId())
                    .setUpdateTime(new Date()).setCreateTime(new Date()).setDataDate(dataDate)
                    .setState("0").setIsRetry("1"));

            try {
                send(issueLog);
            } catch (JsonProcessingException e) {
                issueLogMapper.updateLog(new IssueLog().setId(issueLog.getId())
                        .setState("3").setUpdateTime(new Date()).setReason("发送MQ消息失败"));
                log.error("客群立即下发任务失败"+issueLog.getId(), e);
            }

        }
    }

    @Override
    public void test(String logId, String state, String reason) {
        issueLogMapper.updateLog(new IssueLog().setId(logId)
                .setState(state).setUpdateTime(new Date()).setReason(reason));
    }


    @Transactional(rollbackFor = Exception.class)
    public void send(IssueLog issueLog) throws JsonProcessingException {
        if(StringUtils.isBlank(issueLog.getId())){
            return;
        }
        IssueMqMsg issueMqMsg = new IssueMqMsg();
        issueMqMsg.setId(issueLog.getId());
        String msg = objectMapper.writeValueAsString(issueMqMsg);
        rocketMQTemplate.convertAndSend(MQConfig.FILE_ISSUE_TOPIC, msg);
        issueLogMapper.updateLog(new IssueLog().setId(issueLog.getId())
                .setState("1").setUpdateTime(new Date()));
    }

    private void check(String frequency){
        if(!StringUtils.equals("4",frequency)){
            throw new CustomersException(new ExceptionCode(999,"不支持的下发频度"));
        }
    }
}
